package com.mingqijia.gassafety.authority.security.facade;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mingqijia.gassafety.authority.api.req.manager.ChangePasswordReqDTO;
import com.mingqijia.gassafety.authority.api.req.manager.CreateManagerReqDTO;
import com.mingqijia.gassafety.authority.api.req.manager.QueryManagerReqDTO;
import com.mingqijia.gassafety.authority.api.req.manager.UpdateManagerReqDTO;
import com.mingqijia.gassafety.authority.api.req.misc.Message;
import com.mingqijia.gassafety.authority.api.resp.manager.ManagerRespDTO;
import com.mingqijia.gassafety.authority.api.web.facade.ManagerManageFacade;
import com.mingqijia.gassafety.authority.dal.command.ChangePasswordCommand;
import com.mingqijia.gassafety.authority.dal.command.RemoveManagerCommand;
import com.mingqijia.gassafety.authority.dal.command.UpdateManagerCommand;
import com.mingqijia.gassafety.authority.dal.handler.ManagerTranslator;
import com.mingqijia.gassafety.authority.dal.helper.ConfigureHolder;
import com.mingqijia.gassafety.authority.dal.provider.CompanyProvider;
import com.mingqijia.gassafety.authority.dal.provider.ManagerProvider;
import com.mingqijia.gassafety.authority.domain.adapter.BenAdapter;
import com.mingqijia.gassafety.authority.security.provider.AuthorityProvider;
import com.mingqijia.gassafety.authority.security.user.SecurityUserLoginHolder;
import com.mingqijia.gassafety.db.entity.auth.CompanyEntry;
import com.mingqijia.gassafety.db.entity.auth.ManagerEntry;
import com.mingqijia.gassafety.shared.constant.Constants;
import com.mingqijia.gassafety.shared.cqrs.MessageEvent;
import com.mingqijia.gassafety.shared.enums.RunningState;
import com.mingqijia.gassafety.shared.enums.SmsType;
import com.mingqijia.gassafety.shared.enums.YesNoEnum;
import com.mingqijia.gassafety.shared.facade.BaseFacade;
import com.mingqijia.gassafety.shared.handler.GlobalAuthenticationException;
import com.mingqijia.gassafety.shared.utils.ApplicationUtils;
import com.mingqijia.gassafety.shared.utils.MappingTools;
import com.mingqijia.gassafety.shared.utils.commonUtils.PageUtil;
import com.mingqijia.gassafety.shared.handler.GlobalAuthenticationException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * REST接口
 * @author Damon S.
 * @version v0.2
 * @date 2021-06-19
 */
@Slf4j
@RestController
@RequiredArgsConstructor
public class ManagerManageFacadeImpl extends BaseFacade implements ManagerManageFacade {

    private final ManagerProvider provider;
    private final ManagerTranslator translator;
    private final CompanyProvider cProvider;
    private final BenAdapter benAdapter;
    private final ConfigureHolder holder;
    private final AuthorityProvider provider1;
    private final SecurityUserLoginHolder mHolder;

    @Override
    public PageUtil<ManagerRespDTO> findManager(@Valid QueryManagerReqDTO req) {
        Page<ManagerEntry> results = provider.find(translator.toCommand(req));
        return PageUtil.init(results, provider.buildManagerRel(results.getRecords()));
    }

    @Override
    public String createManager(CreateManagerReqDTO req) {
        String userId = this.provider.create(translator.toCommand(req));
        // 发送短信
        ManagerEntry entry = this.provider.getById(userId);
        Message message = Message.builder().phone(entry.getPhone()).username(entry.getUsername())
                .code(Constants.DEFAULT_PWD).type(SmsType.REGISTER).name(entry.getName()).build();
        ApplicationUtils.CTX.publishEvent(new MessageEvent(this, message));

        try {
            // 历史问题的处理方案: 在本安用户表插入新建用户
            doBenNewUserLogic(userId);
        } catch (Exception e) {
            log.error("在本安用户表插入新建用户失败", e);
        }
        return userId;
    }

    @Override
    public void changePassword(ChangePasswordReqDTO req) {
        if (provider1.checkCaptcha(req.getUsername(), req.getCaptcha())) {
            throw new GlobalAuthenticationException("验证码错误");
        }
        ChangePasswordCommand command = translator.toCommand(req);
        if (!provider.changePassword(command)) {
            throw new GlobalAuthenticationException("变更密码失败，请联系管理员");
        }
    }

    @Override
    public void resetPassword(String userId) {
        String password = provider.resetPassword(userId);
        if (StringUtils.isEmpty(password)) {
            throw new GlobalAuthenticationException("重置密码失败，请联系管理员");
        }
        // 发送短信
        ManagerEntry entry = provider.getById(userId);
        Message message = Message.builder().name(entry.getName()).code(password)
                .type(SmsType.RESET_PWD).phone(entry.getPhone()).build();
        ApplicationUtils.CTX.publishEvent(new MessageEvent(this, message));
    }

    @Override
    public void updateManager(UpdateManagerReqDTO req) {
        if (!provider.update(translator.toCommand(req))) {
            throw new GlobalAuthenticationException("操作失败");
        }
        mHolder.whenManagerUpdated(req.getUserId());
    }

    @Override
    public void removeManager(String[] userId) {
        RemoveManagerCommand command = RemoveManagerCommand.builder()
                .userIds(Arrays.asList(userId)).build();
        provider.remove(command);
    }

    @Override
    public void switchManager(String userId, Integer state) {
        if (state > Constants.INT_ONE || state < Constants.INT_ZERO) {
            throw new GlobalAuthenticationException("请求参数不合法");
        }
        UpdateManagerCommand command = UpdateManagerCommand.builder()
                .userId(userId).state(RunningState.parse(state)).build();
        if (!provider.update(command)) {
            throw new GlobalAuthenticationException("失败");
        }
    }

    private void doBenNewUserLogic(String userId) {
        String value = holder.getConfigByKey("benan_enabled");
        if (StringUtils.isEmpty(value) || !YesNoEnum.parse(value).isFlag()) {
            log.info("本安系统关联操作关闭，不执行");
            return;
        }

        ManagerEntry entry = provider.getById(userId);
        List<String> hierarchies = MappingTools.fromRaw(entry.getHierarchy());

        CompanyEntry spEntry = cProvider.getById(
                hierarchies.get(hierarchies.size() - Constants.INT_ONE)
        );
        if (Objects.nonNull(spEntry)) {
            benAdapter.createUser(spEntry.getRelId(), entry.getUsername(), null);
            return;
        }
        log.error("新创建的用户所在部门不存在[username={}], 本安用户表未生成数据-100101",
                entry.getUsername());
        throw new GlobalAuthenticationException("新创建的用户所在部门不存在-100101");
    }
}
